/*
 * Copyright (c) 2025 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import { TypeNode, SyntaxKind } from 'ts-morph';
import { PropertyKind, TypeStructure, SerializerMetadata } from '../Types';
import { BaseTypeHandler } from './BaseTypeHandler';
import { ITypeHandler } from './ITypeHandler';

abstract class PrimitiveHandler extends BaseTypeHandler implements ITypeHandler {
  abstract readonly name: string;
  abstract readonly kind: PropertyKind;
  abstract readonly syntaxKind: SyntaxKind;

  readonly priority = 100; // 基础类型高优先级

  // ==================== 阶段1: 类型识别 ====================

  matches(typeNode: TypeNode): boolean {
    return typeNode.getKind() === this.syntaxKind;
  }

  // ==================== 阶段2: 类型解析 ====================

  parse(typeNode: TypeNode): TypeStructure {
    return {
      kind: this.kind,
      depth: 0,
      sourceText: typeNode.getText(),
      args: [], // 基础类型没有泛型参数
      dependencies: [] // 基础类型不需要依赖其他类型
    };
  }

  getSerializerMetadata(structure: TypeStructure, withParam?: string): SerializerMetadata {
    const serializerName = this.getSerializerName();
    const defaultInstantiation = this.generateInstantiation(); // 基础类型使用单例

    return {
      name: serializerName,
      typeDeclaration: serializerName,
      instantiationTemplate: this.applyWithParam(withParam, defaultInstantiation, structure),
      encodeMethod: `encode${this.getTypeName()}Element`,
      decodeMethod: `decode${this.getTypeName()}`,
      decoderType: `${structure.sourceText} | undefined`,
      needsTypeAssertion: false
    };
  }

  // ==================== 阶段4: 代码生成 ====================

  generateInstantiation(): string {
    const serializerName = this.getSerializerName();
    return `${serializerName}.INSTANCE`;
  }

  generateTypeDeclaration(): string {
    return this.getSerializerName();
  }

  generateTypeKey(structure: TypeStructure): string {
    // 类型键为字符串形式
    return `'${structure.sourceText}'`;
  }

  // ==================== Sendable转换 ====================

  generateSendableTypeDeclaration(structure: TypeStructure): string {
    // 基础类型在Sendable中不需要转换，直接返回原类型
    return structure.sourceText;
  }

  generatePropertyConversion(_structure: TypeStructure, sourceValue: string): string {
    // 基础类型在两个方向都直接传递，不需要转换
    return sourceValue;
  }
}

class StringHandler extends PrimitiveHandler {
  readonly name = 'StringHandler';
  readonly kind = PropertyKind.STRING;
  readonly syntaxKind = SyntaxKind.StringKeyword;
}

class NumberHandler extends PrimitiveHandler {
  readonly name = 'NumberHandler';
  readonly kind = PropertyKind.NUMBER;
  readonly syntaxKind = SyntaxKind.NumberKeyword;
}

class BooleanHandler extends PrimitiveHandler {
  readonly name = 'BooleanHandler';
  readonly kind = PropertyKind.BOOLEAN;
  readonly syntaxKind = SyntaxKind.BooleanKeyword;
}

class BigintHandler extends PrimitiveHandler {
  readonly name = 'BigintHandler';
  readonly kind = PropertyKind.BIGINT;
  readonly syntaxKind = SyntaxKind.BigIntKeyword;
}

class NullHandler extends PrimitiveHandler {
  readonly name = 'NullHandler';
  readonly kind = PropertyKind.NULL;
  readonly syntaxKind = SyntaxKind.NullKeyword;

  // Override matches: null类型的节点是LiteralType
  matches(typeNode: TypeNode): boolean {
    // 检查是否是字面量类型节点
    if (typeNode.getKind() === SyntaxKind.LiteralType) {
      const literal = typeNode.asKindOrThrow(SyntaxKind.LiteralType);
      const literalValue = literal.getLiteral();
      return literalValue.getKind() === SyntaxKind.NullKeyword;
    }
    // 兼容直接的NullKeyword节点
    return typeNode.getKind() === SyntaxKind.NullKeyword;
  }
}

class UndefinedHandler extends PrimitiveHandler {
  readonly name = 'UndefinedHandler';
  readonly kind = PropertyKind.UNDEFINED;
  readonly syntaxKind = SyntaxKind.UndefinedKeyword;

  // Override matches: undefined也可能以字面量形式出现
  matches(typeNode: TypeNode): boolean {
    // 检查是否是字面量类型节点
    if (typeNode.getKind() === SyntaxKind.LiteralType) {
      const literal = typeNode.asKindOrThrow(SyntaxKind.LiteralType);
      const literalValue = literal.getLiteral();
      return literalValue.getKind() === SyntaxKind.UndefinedKeyword;
    }
    // 兼容直接的UndefinedKeyword节点
    return typeNode.getKind() === SyntaxKind.UndefinedKeyword;
  }
}

export function createPrimitiveHandlers(): ITypeHandler[] {
  return [
    new StringHandler(),
    new NumberHandler(),
    new BooleanHandler(),
    new BigintHandler(),
    new NullHandler(),
    new UndefinedHandler()
  ];
}